// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
 *    NAND Flash Controller nand Device Driver
 *    Copyright (c) 2009-2010 by Hisilicon.
 *    All rights reserved.
 * ***
 *
 ******************************************************************************/
#ifndef HIBASE_H
#define HIBASE_H
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <mach/kexport.h>
#include <asm/setup.h>

#define MAX_MTD_PARTITIONS              32
#define MTD_PARTITIONS_NAME_LEN         16

#define HINP_ASCII                      0x48694E70
#define HI_READ_CHIPID_MAGIC            0x118417

/* FMC/HINFC301 status register to detect the maximum number of polls */
#define HI_NAND_CHECK_STATUS_LOOP_MAX   10000000
#define HI_NAND_STATUS_START            0x1
#define HI_NAND_CHIP_RESET_DELAY        50

#ifndef CONFIG_HINFC301_HARDWARE_PAGESIZE_ECC
#define CONFIG_HINFC301_HARDWARE_PAGESIZE_ECC 1
#endif

#define NAND_MAX_OOBSIZE        512
#define NAND_MAX_PAGESIZE       8192

#define hinfc_read(_host, _reg) \
	((unsigned int)readl((char *)_host->iobase + (_reg)))
#define hinfc_write(_host, _value, _reg) \
	writel((_value), (char *)_host->iobase + (_reg))
#define hinfc_write(_host, _value, _reg) \
	writel((_value), (char *)_host->iobase + (_reg))

#define DBG_BUG(fmt, args...) do { \
	pr_err("%s(%d): !!! BUG " fmt, __func__, __LINE__, ##args); \
	while (1) \
		; \
} while (0)

#define GET_PAGE_INDEX(host) \
	((host->addr_value[0] >> 16) | (host->addr_value[1] << 16))

struct hinfc_ewe_count {
	unsigned int ui_erasetimes;
	unsigned int ui_writetimes;
	unsigned int ui_co_ecc_err;
	unsigned int ui_unco_ecc_err;
};

struct partition_entry {
	char name[MTD_PARTITIONS_NAME_LEN];
	unsigned long long start;
	unsigned long long length;
	unsigned int flags;
};

struct partition_info {
	int parts_num;
	struct partition_entry entry[MAX_MTD_PARTITIONS];
	struct mtd_partition parts[MAX_MTD_PARTITIONS];
};

struct code {
	unsigned int opcode;
	unsigned int dummy;
	unsigned int if_type;
};

struct die_info {
	unsigned int die_num;
	unsigned int die_cmd;
};

struct op_code {
	struct code rd_code;
	struct code wr_code;
	unsigned int erase_code;
	struct die_info die_code;
};

struct hinfc_host {
	struct nand_chip *chip;
	struct mtd_info *mtd;
	void __iomem *iobase;
	void __iomem *sysreg;
	struct device *dev;

	unsigned int offset;
	unsigned int command;

	unsigned int chipselect;

	unsigned int n24bit_ext_len;
	unsigned int ecctype;

	unsigned long NFC_CON;
	unsigned long NFC_CON_ECC_NONE;
	unsigned long hw_pagesize;
	unsigned long hw_blocksize;

	unsigned int addr_cycle;
	unsigned int addr_value[2];
	unsigned int column;

	unsigned int dma_oob;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
	unsigned long long dma_buffer;
#else
	unsigned int dma_buffer;
#endif
	unsigned int pagesize;
	unsigned int oobsize;
	char *buffer;

	unsigned int uc_er;

	int flashtype;
	struct op_code opcode;
};

uint8_t hi_read_byte(struct nand_chip *chip);
u16 hi_read_word(struct nand_chip *chip);
void hi_write_buf(struct nand_chip *chip, const uint8_t *buf, int len);
char *int_to_size(unsigned long long size);
void hi_reg_status_check(struct hinfc_host *host, unsigned int reg);
int hi_reg_status_check_mdelay(struct hinfc_host *host, unsigned int reg);
void hinand_of_node_parse(struct platform_device *dev, const char *of_name);

extern struct hinfc_ewe_count g_nand_ewetimes;

#endif
